package com.yixia.web.controller.system;

import com.yixia.common.annotation.Log;
import com.yixia.common.constant.UserConstants;
import com.yixia.common.core.controller.BaseController;
import com.yixia.common.core.domain.AjaxResult;

import com.yixia.common.core.domain.entity.SysMenu;
import com.yixia.common.enums.BusinessType;
import com.yixia.common.utils.SecurityUtils;
import com.yixia.common.utils.StringUtils;
import com.yixia.system.service.system.SysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 菜单管理
 *
 * @author: yimeng
 */
@Api(tags = "菜单管理模块")
@Slf4j
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController {

    @Autowired
    private SysMenuService menuService;

    /**
     * COMMIT : 已完成
     * 获取菜单列表
     */
    @ApiOperation("条件查询")
    @PostMapping("/list")
    @PreAuthorize("@yixia.hasPermi('system:menu:list')")
    public AjaxResult list(@RequestBody SysMenu sysMenu) {
        /*根据用户id查询菜单列表*/
        List<SysMenu> menuList = menuService.selectMenuList(sysMenu, SecurityUtils.getUserId());
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("menuList", menuList);
        return AjaxResult.success(resultMap);
    }


    /**
     * 新增菜单
     */
    @PostMapping("/add")
    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
    @PreAuthorize("@yixia.hasPermi('system:menu:add')")
    public AjaxResult add(@Validated @RequestBody SysMenu menu) {
        log.info("添加菜单" + menu.getMenuName());
        /*1.先查看该菜单名是否已经存在*/
        if (menuService.checkMenuNameUnique(menu)) {
            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
        }
        /*2.再对要添加的菜单的格式进行二次检测*/
        if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
        }
        /*3.最后再进行添加*/
        return toAjax(menuService.save(menu));
    }


    /**
     * 判断菜单名是否存在
     */
    @PostMapping("/checkMenuNameUnique")
    public AjaxResult checkMenuNameUnique(@RequestBody SysMenu menu) {
        if (!menuService.checkMenuNameUnique(menu)) {
            return AjaxResult.error("该菜单已存在！");
        }
        return AjaxResult.success("可以添加");
    }


    /**
     * 删除菜单system:menu:remove
     *
     * @param menuId
     * @return
     */
    @DeleteMapping("/delete/{menuId}")
    public AjaxResult remove(@PathVariable("menuId") Long menuId) {
        /*1.先判断是否存在子菜单，存在则不允许删除*/
        if (menuService.hasChildByMenuId(menuId)) {
            return AjaxResult.error("存在子菜单,不允许删除");
        }
        /*2.判断该菜单是否分配查询菜单角色表sys_menu_role*/
        if (menuService.checkMenuExistRole(menuId)) {
            return AjaxResult.error("菜单已分配,不允许删除");
        }
        /*3.可以删除进行删除*/
        boolean remove;
        try {
            remove = menuService.removeById(menuId);
        } catch (RuntimeException e) {
            return AjaxResult.error(e.getMessage());
        }
        if (remove) {
            return AjaxResult.success("删除成功");
        }
        return AjaxResult.error("删除失败");
    }

    /**
     * 修改菜单
     * @param menu
     * @return
     */
    @PutMapping("/edit")
    public AjaxResult edit(@Validated @RequestBody SysMenu menu) {
        /*1.要先判断在当前目录下该要修改的菜单名是否存在*/
        /*2.判断修改后的外链中的菜单路径是否可以*/
        /*3.上级菜单不能修改*/
        if (menuService.checkMenuNameUnique(menu)) {
            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
        } else if (menu.getMenuId().equals(menu.getParentId())) {
            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败，上级菜单不能选择自己");
        }
        /*4.根据id进行修改*/
        if (menuService.updateById(menu)) {
            return AjaxResult.success("修改成功");
        }
        return AjaxResult.error("数据库修改失败!");
    }

    /**
     * COMMIT : 已完成
     * 根据id获取菜单信息
     */
    @GetMapping("/info/{menuId}")
    public AjaxResult getInfo(@PathVariable Long menuId) {
        SysMenu menuById = menuService.getById(menuId);
        if (StringUtils.isNotNull(menuById)) {
            return AjaxResult.success("操作成功", menuById);
        }
        return AjaxResult.error("查找失败");
    }

    /**
     * COMMIT: 已完成
     * 获取菜单下拉树列表
     */
    @GetMapping("/treeSelect")
    public AjaxResult treeSelect(SysMenu sysMenu) {
        /*根据用户id获取菜单信息*/
        List<SysMenu> menus = menuService.selectMenuList(sysMenu, getUserId());
        return success(menuService.buildMenuTreeSelect(menus));
    }

    /**
     * 加载对应角色菜单列表树
     */
    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
    public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
        List<SysMenu> menus = menuService.selectMenuList(getUserId());
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
        return ajax;
    }
}
